﻿Imports System.Diagnostics
Imports PhDir.Repository.Phone

Namespace Repository
    Public Class PhoneRepository

        Public Delegate Function SearchMethod(ByVal plainPhoneNumber As String) As List(Of Model.Phone)

        Friend Sub New()
            Me.SelectAllPhones            = New SelectAllPhones()
            Me.SearchPlainPhoneNumber     = New SearchPlainPhone()
            Me.SearchEncryptedPhoneNumber = New SearchEncryptedPhone()
            Me.SearchPhoneByName          = New SearchPhoneByName()
            Me.SearchPhoneByDepartment    = New SearchPhoneByDepartment()
            Me.InsertNewPhoneNumber       = New InsertNewPhone()
            Me.UpdatePhoneNumber          = New UpdatePhoneNumber()
            Me.DeletePhoneNumber          = New DeletePhoneNumber()
        End Sub

        Private Property SelectAllPhones            As ISelectAll(Of Model.Phone)
        Private Property SearchPlainPhoneNumber     As ISearch(Of Model.Phone, String)
        Private Property SearchEncryptedPhoneNumber As ISearch(Of Model.Phone, String)
        Private Property SearchPhoneByName          As ISearch(Of Model.Phone, String)
        Private Property SearchPhoneByDepartment    As ISearch(Of Model.Phone, String)
        Private Property InsertNewPhoneNumber       As IInsert(Of Model.Phone)
        Private Property UpdatePhoneNumber          As IUpdate(Of Model.Phone)
        Private Property DeletePhoneNumber          As IDelete(Of Model.Phone)

        Public Function SelectAll() As List(Of Model.Phone)
            Return Me.SelectAllPhones.SelectAll()
        End Function

        Public Function SearchPlain(ByVal plainPhoneNumber As String) As List(Of Model.Phone)
            Return Me.SearchPlainPhoneNumber.Search(plainPhoneNumber)
        End Function

        Public Function SearchEncrypted(ByVal plainPhoneNumber As String) As List(Of Model.Phone)
            Return Me.SearchEncryptedPhoneNumber.Search(plainPhoneNumber)
        End Function

        Public Function SearchByName(ByVal name As String) As List(Of Model.Phone)
            Return Me.SearchPhoneByName.Search(name)
        End Function

        Public Function SearchByDepartment(ByVal departmentName As String) As List(Of Model.Phone)
            Return Me.SearchPhoneByDepartment.Search(departmentName)
        End Function

        ''' <summary>
        ''' Timing the execution time of either SearchPlain or SearchEncrypted
        ''' </summary>
        ''' <param name="phone"></param>
        ''' <param name="searchMethod">Either SearchPlain or SearchEncrypted</param>
        ''' <param name="executionTime"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function TimingSearch(ByVal phone As String,
                                    ByVal searchMethod As SearchMethod,
                                    ByRef executionTime As TimeSpan) As List(Of Model.Phone)
            Dim phones As List(Of Model.Phone)
            Dim stopWatch As Stopwatch = New Stopwatch()

            stopWatch.Start()
            phones = searchMethod(phone)
            stopWatch.Stop()

            executionTime = stopWatch.Elapsed

            Return phones
        End Function

        Public Function Insert(ByVal phone As Model.Phone) As Boolean
            Return Me.InsertNewPhoneNumber.Insert(phone)
        End Function

        Public Function Update(ByVal oldPhone As Model.Phone, ByVal newPhone As Model.Phone) As Boolean
            Return Me.UpdatePhoneNumber.Update(oldPhone, newPhone)
        End Function

        Public Function Delete(ByVal phone As Model.Phone) As Boolean
            Return Me.DeletePhoneNumber.Delete(phone)
        End Function
    End Class
End Namespace
